/**
 * @file 预加载脚本 - 全局状态管理桥接
 * @description 通过 contextBridge 为渲染进程提供安全的全局状态管理 API 接口
 * 实现主进程与渲染进程间的安全通信，支持运行时状态和持久性状态的管理
 *
 * ## 核心功能
 * - 🔒 **安全通信**: 通过 contextBridge 确保进程间安全通信
 * - 📡 **双向同步**: 支持状态获取、设置和实时更新通知
 * - 🎯 **类型安全**: 提供完整的 TypeScript 类型定义
 * - ⚡ **高效传输**: 基于 IPC 的高效数据传输机制
 *
 * @author 黄敏
 * @version 1.0.0
 * @since 2025-05-28
 * @updated 2025-01-27 优化注释和文档结构
 */

import { topic } from '../common/config'
// 使用 require 方式导入 electron 以兼容预加载环境
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-require-imports
const electron = require('electron')

/**
 * 全局状态管理 API 对象
 * @description 为渲染进程提供完整的状态管理功能，包括持久性状态和运行时状态的操作
 * 所有方法都支持完整的 TypeScript 类型检查，确保类型安全
 */
const globalState = {
  /** 持久性状态管理 API */
  storage: {
    /**
     * 获取持久性状态
     * @template Default 状态对象类型
     * @param name 状态名称标识符
     * @param options 可选配置，包含默认值、版本信息和存储选项
     * @returns 完整的状态对象
     */
    get: <Default extends Record<string, unknown>>(
      name: string,
      options?: {
        defaults: Default;
        version: number;
        options?: { skipDefaultsCheck?: boolean }
      }
    ) => {
      return electron.ipcRenderer.sendSync(topic.get, name, options) as Default
    },

    /**
     * 设置持久性状态
     * @template Default 状态对象类型
     * @param name 状态名称标识符
     * @param value 要设置的状态值，可以是完整对象或单个属性值
     * @param key 可选的属性键名，用于设置单个属性
     */
    set: <Default extends Record<string, unknown>>(
      name: string,
      value: Default | Default[keyof Default],
      key?: keyof Default
    ) => {
      electron.ipcRenderer.send(topic.set, name, value, key)
    },

    /**
     * 监听持久性状态更新
     * @template Default 状态对象类型
     * @param name 状态名称标识符
     * @param keyOrCallback 键名或回调函数 - 传入键名时监听特定属性，传入函数时监听完整状态
     * @param callback 回调函数，仅当第二个参数为键名时使用
     */
    onStateUpdated: <Default extends Record<string, unknown>>(
      name: string,
      keyOrCallback: keyof Default | ((data: Default) => void),
      callback?: (data: Default[keyof Default]) => void
    ) => {
      if (typeof keyOrCallback === 'string' && callback) {
        const cb = (_: unknown, data: Default[keyof Default]) => callback(data)

        // 监听特定属性的更新
        electron.ipcRenderer.on(`${topic.update}-${name}-${keyOrCallback}`, cb)
        return () => {
          electron.ipcRenderer.off(`${topic.update}-${name}-${keyOrCallback}`, cb)
        }
      } else if (typeof keyOrCallback === 'function') {
        const cb = (_: unknown, data: Default) => keyOrCallback(data)
        // 监听完整状态对象的更新
        electron.ipcRenderer.on(`${topic.update}-${name}`, cb)
        return () => {
          electron.ipcRenderer.off(`${topic.update}-${name}`, cb)
        }
      }
    }
  },

  /** 运行时状态管理 API */
  runtime: {
    /**
     * 获取运行时状态
     * @template T 状态值类型
     * @param key 状态键名
     * @returns 当前状态值
     */
    get: <T>(key: string) => {
      return electron.ipcRenderer.sendSync(topic.getRuntime, key) as T
    },

    /**
     * 设置运行时状态
     * @param key 状态键名
     * @param value 要设置的状态值
     */
    set: (key: string, value: unknown) => {
      electron.ipcRenderer.send(topic.setRuntime, { key, value })
    },

    /**
     * 清除运行时状态
     * @param key 要清除的状态键名
     */
    clear: (key: string) => {
      electron.ipcRenderer.send(topic.clearRuntime, key)
    },

    /**
     * 监听运行时状态更新
     * @param key 状态键名
     * @param callback 状态变更回调函数，接收新值和旧值
     */
    onStateUpdated: (
      key: string,
      callback: (data: { newValue: unknown; oldValue: unknown }) => void
    ) => {
      electron.ipcRenderer.on(
        `${topic.updateRuntime}-${key}`,
        (_: unknown, data: { key: string; oldValue: unknown; newValue: unknown }) => callback(data)
      )

      return () => {
        electron.ipcRenderer.off(`${topic.updateRuntime}-${key}`, callback)
      }
    }
  }
}


/**
 * 通过 contextBridge 暴露全局状态管理 API
 * @description 将状态管理 API 安全地暴露到渲染进程的全局作用域
 * 渲染进程可通过 `_globalState_` 全局对象访问所有状态管理功能
 */
electron.contextBridge.exposeInMainWorld('_globalState_', globalState)

/**
 * 全局类型声明
 * @description 为 TypeScript 提供全局 `_globalState_` 对象的类型定义
 * 确保在渲染进程中可以获得完整的类型检查和智能提示支持
 */
declare global {
  /**
   * 全局状态管理对象
   * @description 在渲染进程中可用的全局状态管理 API
   * 提供类型安全的全局状态访问和操作功能
   *
   * @example
   * ```typescript
   * // 获取运行时状态
   * const theme = _globalState_.runtime.get<'dark' | 'light'>('theme')
   *
   * // 设置运行时状态
   * _globalState_.runtime.set('theme', 'dark')
   *
   * // 获取持久性状态
   * const settings = _globalState_.storage.get('userSettings', { defaults: {}, version: 1 })
   *
   * // 监听状态变化
   * _globalState_.runtime.onStateUpdated('theme', (data) => {
   *   console.log('主题已变更:', data.newValue)
   * })
   * ```
   */
  const _globalState_: Readonly<typeof globalState>
}
